博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django ModelForm组件
阅读量:6310 次
发布时间:2019-06-22

本文共 6780 字,大约阅读时间需要 22 分钟。

一、创建ModelForm

from django.forms import ModelFormfrom appxx import modelsfrom django.forms import widgets as wdt  # 因为重名,所以起个别名#定义一个类,比如BookForm,这个类要继承ModelForm,在这个类中再写一个原类Meta(规定写法,注意首字母是大写的)#在这个原类中,有以下属性(部分):class BookForm(ModelForm):    class Meta:        model = models.Book  # 对应的Model中的类        fields = "__all__" # 字段,如果是__all__,就表示列出所有的字段,或者使用列表列出想要的字段        exclude = None  # 排除的字段        # error_messages用法        error_messages = {            "title": {
"required": "书名不能为空"}, "price": {
"required": "售价不能为空"}, } # widgets用法,比如把输入用户名的input框给为Textarea widgets = { "name": wdt.Textarea(attrs={
"class": "c1"}) # 还可以自定义属性 } #labels,自定义在前端显示的名字 labels= { "title": "书名", "price": "售价", }

然后在 url 对应的视图函数中实例化这个类,把这个对象传给前端:

def add_book(request):    form = forms.BookForm()    return render(request, "add_book.html", {
"form": form})

然后在前端像Form组件那样渲染页面,

二、添加数据

保存数据的时候,不用挨个取数据了,只需要 save 一下即可。

from django.shortcuts import render,redirectfrom appxx import modelsfrom appxx import formsdef add_book(request):    if request.method == "POST":        form = forms.BookForm(request.POST)        if form.is_valid():            form.save()            return redirect("/book/")    form = forms.BookForm()    return render(request, "add_book.html", {
"form": form})

三、编辑数据

如果不使用 ModelForm,编辑的时候得显示之前的数据,还得挨个取一遍值;如果使用 ModelForm,只需要加一个instance=obj(obj是要修改的数据库的一条数据的对象)就可以得到同样的效果。

保存的时候要注意,一定要注意有这个对象(instance=obj),否则不知道更新哪一个数据。

from django.shortcuts import render,redirectfrom appxx import modelsfrom appxx import formsdef edit_book(request, edit_book_id):    edit_book= models.Book.objects.filter(id=edit_book_id).first()    if request.method == "POST":        form = forms.BookForm(request.POST, instance=edit_book)        if form.is_valid():            form.save()            return redirect("/book/")    form = forms.BookForm(instance=edit_book)    return render(request, "edit_book.html", {
"form": form})

总结: 从上边可以看到 ModelForm 用起来是非常方便的,比如增加修改之类的操作。但是也带来额外不好的地方,model和form之间耦合了。如果不耦合的话,form.save()方法也无法直接提交保存。 但是耦合的话使用场景通常局限用于小程序,写大程序就最好不用了。

四、完整示例代码

项目结构

urls.py

from django.conf.urls import urlfrom django.contrib import adminfrom appxx import viewsurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r"^book/$", views.book),    url(r"^book/add/", views.add_book),    url(r"^book/edit/(\d+)/", views.edit_book),]

views.py

from django.shortcuts import render,redirectfrom appxx import modelsfrom appxx import formsdef book(request):    book_list = models.Book.objects.all()    return render(request, "book.html", {
"book_list": book_list})def add_book(request): if request.method == "POST": form = forms.BookForm(request.POST) if form.is_valid(): form.save() return redirect("/book/") form = forms.BookForm() return render(request, "add_book.html", {
"form": form})def edit_book(request, edit_book_id): edit_book= models.Book.objects.filter(id=edit_book_id).first() if request.method == "POST": form = forms.BookForm(request.POST, instance=edit_book) if form.is_valid(): form.save() return redirect("/book/") form = forms.BookForm(instance=edit_book) return render(request, "edit_book.html", {
"form": form})

models.py

from django.db import modelsclass Book(models.Model):    id = models.AutoField(primary_key=True)    title = models.CharField(max_length=32)    price = models.DecimalField(max_digits=5, decimal_places=2)    publish_date = models.DateField()    publisher = models.ForeignKey(to="Publisher")    authors = models.ManyToManyField(to="Author")    def __str__(self):        return self.titleclass Publisher(models.Model):    id = models.AutoField(primary_key=True)    name = models.CharField(max_length=32)    def __str__(self):        return self.nameclass Author(models.Model):    id = models.AutoField(primary_key=True)    name = models.CharField(max_length=32)    def __str__(self):        return self.name

forms.py

from django.forms import ModelFormfrom appxx import modelsfrom django.forms import widgets as wdtclass BookForm(ModelForm):    class Meta:        model = models.Book        fields = "__all__"        labels = {            "title": "书名",            "price": "售价",            "publish_date": "出版日期",            "publisher": "出版社",            "authors": "作者"        }        widgets = {            "title": wdt.TextInput(attrs={
"class": "form-control"}), "price": wdt.TextInput(attrs={
"class": "form-control"}), "publish_date": wdt.TextInput(attrs={
"class": "form-control", "type": "date"}), "publisher": wdt.Select(attrs={
"class": "form-control"}), "authors": wdt.SelectMultiple(attrs={
"class": "form-control"}), } error_messages = { "title": {
"required": "书名不能为空"}, "price": {
"required": "售价不能为空"}, "publish_date": {
"required": "出版日期不能为空"}, "publisher": {
"required": "出版社不能为空"}, "authors": {
"required": "作者不能为空"}, }

book.html

    
展示书籍
添加
{% for book in book_list %}
{% endfor %}
序号 书名 售价 出版日期 出版社 作者 操作
{ { forloop.counter }} { { book.title }} { { book.price }} { { book.publish_date }} { { book.publisher.name }} {% for author in book.authors.all %} { { author.name }} {% endfor %} 编辑 删除
View Code

add_book.html和edit_book.html(两个页面代码一样) 

    
添加书籍
{# panel开始 #}

添加书籍

{# panel-body开始 #}
{# form开始 #}
{% csrf_token %}
{ { form.title }}
{ { form.price }}
{ { form.publish_date }}
{ { form.publisher }}
{ { form.authors }}
取消
{# form结束 #}
{# panel-body结束 #}
{# panel结束 #}
View Code

 

转载于:https://www.cnblogs.com/believepd/p/10067679.html

你可能感兴趣的文章
linux内核编程笔记【原创】
查看>>
ORA-02085: database link %s connects to %s 解决思路
查看>>
DB2常用命令
查看>>
HTTP Server Error 500 内部服务器错误
查看>>
让树莓派说出自己的IP地址
查看>>
转--发布js支持Firefox的加入收藏代码
查看>>
nyoj 322 Sort 【树阵】
查看>>
Impala通过JDBC方式访问
查看>>
前端如何正确选择offer,到底选哪个?
查看>>
基于ARM处理器的反汇编器软件简单设计及实现
查看>>
Google Zxing 二维码生成与解析
查看>>
浅谈Hive和HBase区别
查看>>
C语言将字符串转换成对应的数字(十进制、十六进制)【转】
查看>>
据说每个大牛、小牛都应该有自己的库——框架篇
查看>>
EntityFramework之原始查询如何查询未映射的值,你又知道多少?
查看>>
target_list 中的 list_make1 的含义
查看>>
PLSQL DBMS_DDL.ALTER_COMPILE
查看>>
[Step By Step]SAP HANA PAL多元指数回归预测分析Multiple Exponential Regression编程实例EXPREGRESSION(模型)...
查看>>
法线贴图是用来解决低模的细节表现问题
查看>>
Adobe AIR中使用Flex连接Sqlite数据库(2)(添加,删除,修改以及语句参数)
查看>>